package com.yan.design.one.principle1.o3;

/**
 * 设计模式 ： 7大原则
 *      3. 依赖倒转原则
 *           中心思想就是面向接口编程，抽象类不应该依赖细节，细节依赖抽象
 *           依赖关系有3种方式传递
 *              1.接口传递 2. 构造传递 3.set方法传递
 * @author shengren.yan
 * @create 2022-07-03
 */
public class principle3 {

    public static void main(String[] args) {

        // 调用者
//        new Person().rece(new Email());  // 发送邮箱
//        new Person().rece(new Werixin());// 发送微信

        // 方式1 接口传递
        OpenAndClose openAndClose = new OpenAndClose();
        openAndClose.open(new  ATV());
        openAndClose.open(new  BTV());

        // 方式2 构造传递
//        OpenAndClose openAndClose = new OpenAndClose(new  ATV());
//        openAndClose.open();
//        OpenAndClose openAndClose2 = new OpenAndClose(new  BTV());
//        openAndClose2.open();

        // 方式3 set方法传递
//        OpenAndClose openAndClose = new OpenAndClose();
//        openAndClose.setTv(new  ATV());
//        openAndClose.setTv(new  BTV());
//        openAndClose.open(); // 需要先set，不然会报空指针

    }


    // 定义接口  案例
    interface IRece{
        public String info();
    }
    class Email implements IRece{
        public String info() {
            return "电子邮件发送--";
        }
    }
    class Werixin implements IRece{
        public String info() {
            return "微信发送--";
        }
    }
    class Person {
        // 发送的时候 - 参数是接口， 之前有邮箱发送，后续有微信，就增加微信类
        public void rece(IRece r) {
            System.out.println(r.info());
        }
        // 调用者
//        new Person().rece(new Email());  // 发送邮箱
//        new Person().rece(new Werixin());// 发送微信
    }



//    方式1：接口传递
    interface IOpenAndClose{
        public void open(ITV tv); // 抽象方法
    }
    static class OpenAndClose implements IOpenAndClose{
        @Override
        public void open(ITV tv) { // 传递方式是接口
            tv.play();
        }
    }
    interface ITV{
        public void play();
    }
    // A类计算机 、如果有B 就需要再创建B类
    static class ATV implements ITV{
        @Override
        public void play() {
            System.out.println("打开ATV---");
        }
    }
    static class BTV implements ITV{
        @Override
        public void play() {
            System.out.println("打开BTV---");
        }
    }


//    方式2：构造传递
//    interface IOpenAndClose{
//        public void open(); // 抽象方法
//    }
//    static class OpenAndClose implements IOpenAndClose{
//        private ITV tv;
//        public OpenAndClose(ITV tv){ //构造器进行传递
//            this.tv=tv;
//        }
//        @Override
//        public void open() {
//            this.tv.play();
//        }
//    }
//    interface ITV{
//        public void play();
//    }
//    // A类计算机 、如果有B 就需要再创建B类
//    static class ATV implements ITV{
//        @Override
//        public void play() {
//            System.out.println("打开ATV---");
//        }
//    }
//    static class BTV implements ITV{
//        @Override
//        public void play() {
//            System.out.println("打开BTV---");
//        }
//    }


    // 方式3 set方法传递
//    interface IOpenAndClose{
//        public void open(); // 抽象方法
//    }
//    static class OpenAndClose implements IOpenAndClose{
//        private ITV tv;
//        public void setTv(ITV tv) {
//            this.tv = tv;
//        }
//        @Override
//        public void open() {
//            this.tv.play();
//        }
//    }
//    interface ITV{
//        public void play();
//    }
//    // A类计算机 、如果有B 就需要再创建B类
//    static class ATV implements ITV{
//        @Override
//        public void play() {
//            System.out.println("打开ATV---");
//        }
//    }
//    static class BTV implements ITV{
//        @Override
//        public void play() {
//            System.out.println("打开BTV---");
//        }
//    }

}
